﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Threading;

namespace FileSharing
{
    public class Diretorio
    {
        protected String Path;
        protected SortedList<String, LocalFile> Files = new SortedList<String, LocalFile>();

        Mutex FilesMut = new Mutex();

        public String Location
        {
            get { return Path; }
            set
            {
                Path = value;

                if (Directory.Exists(Path))
                {
                    Files.Clear();
                    loadFiles(Path);
                }
                else
                    throw new DirectoryNotFoundException();
            }
        }

        public int FilesCount
        {
            get { return Files.Count; }
        }

        protected void loadFiles(String path)
        {
            DirectoryInfo Dir = new DirectoryInfo(path);
            FileInfo[] FileList = Dir.GetFiles();

            foreach (FileInfo file in FileList)
            {
                try
                {
                    Files.Add(file.Name, new LocalFile(file));
                }
                catch (Exception e)
                {
                }
            }

            DirectoryInfo[] DirList = Dir.GetDirectories();

            foreach (DirectoryInfo dirinfo in DirList)
                loadFiles(dirinfo.FullName);
        }

        public LocalFile[] FindFile(String query)
        {
            String[] subQueries = query.ToLower().Split(' ');
            List<LocalFile> result = new List<LocalFile>();

            FilesMut.WaitOne();

            foreach (LocalFile file in Files.Values)
            {
                bool match = true;

                foreach (String q in subQueries)
                {
                    if (!file.Name.ToLower().Contains(q))
                        match = false;
                }

                if (match)
                {
                    result.Add(file);
                }
            }

            FilesMut.ReleaseMutex();

            return result.ToArray();
        }

        public LocalFile FindFile(byte[] hash, Int64 length)
        {
            FilesMut.WaitOne();

            foreach (LocalFile f in Files.Values)
            {
                bool equal = true;
                for (int i = 0; i < hash.Length; i++)
                {
                    if (f.Hash[i] != hash[i])
                    {
                        equal = false;
                        break;
                    }
                }

                if (equal && f.Length == length)
                {
                    FilesMut.ReleaseMutex();

                    return f;
                }
            }

            FilesMut.ReleaseMutex();

            throw new FileNotFoundException(BitConverter.ToString(hash) + ":" + length.ToString());
        }

        public void Refresh()
        {
            if (Directory.Exists(Path))
            {
                FilesMut.WaitOne();

                Files.Clear();
                loadFiles(Path);

                FilesMut.ReleaseMutex();
            }
            else
                throw new DirectoryNotFoundException();
        }
    }
}
